package pure.ui.skins 
{
	import pure.ui.manager.SkinManager;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;
	
	/**
	 * 伸缩自在式皮肤基类
	 * @author Des
	 * 
	 * <TODO>保留空间不得小于4像素
	 * 
	 * 单例:
	 * 
	 *	public class NewRetra
	 *	{
	 *		
	 *		public static function get instance():ClickableRetraSkin
	 *		{
	 *			if (_instance == null) {
	 *				_instance = new ClickableRetraSkin('retraOut', 'retraOver' , 'retraDown');
	 *				_instance.type = RetractileType.HORIZONTAL;
	 *				_instance.setHorizontalSpace(23, 23);
	 *			}
	 *			return _instance;
	 *		}
	 *		private static var _instance:ClickableRetraSkin
	 *	}
	 * 
	 */
	
public class RetractileSkin implements ISkin
{
	/**
	 * @param invalidation		当组件不可交互时的位图定义
	 */
	public function RetractileSkin(invalidation:String = null)
	{
		this.invalidation = invalidation;
	}


	
	/*model*/
	
	protected var _type:int = 3;	// 伸缩类型(默认为完整绘制)
	
	protected var _upSpace:Number=4;	// 上保留空间
	
	protected var _downSpace:Number=4;	// 下保留空间
	
	protected var _leftSpace:Number=4;	// 左保留空间
	
	protected var _rightSpace:Number=4;	// 右保留空间
	
	
	public var invalidation:String;	// 组件不可交互(property)

	
	
	/*cache*/
	
	protected var _widthCache:Number;	// 宽度缓存
	
	protected var _heightCache:Number;	// 高度缓存

	
	
	/**
	 * 垂直保留空间
	 * @param leftSpace				左保留空间
	 * @param rightSpace			右保留空间
	 */
	public function setVerticalSpace(upSpace:Number, downSpace:Number):void
	{
		if (upSpace < 4 || downSpace < 4)
		{
			throw new Error("RetractileSkin::setVerticalSpace - 保留空间不得小于4像素！");
		}
		this._upSpace = upSpace;
		this._downSpace = downSpace;
	}
	
	/**
	 * 水平保留空间
	 * @param leftSpace				左保留空间
	 * @param rightSpace			右保留空间
	 */
	public function setHorizontalSpace(leftSpace:Number, rightSpace:Number):void
	{
		if (leftSpace < 4 || rightSpace < 4)
		{
			throw new Error("RetractileSkin::setHorizontalSpace - 保留空间不得小于4像素！");
		}
		this._leftSpace = leftSpace;
		this._rightSpace = rightSpace;
	}
	
	/**
	 * 获取伸缩位图
	 * @param property		属性名称
	 **/
	public function getBitmap(property:String,currW:Number,currH:Number,app:ApplicationDomain=null):BitmapData
	{
		var definition:String = this[property];
		if (definition == null || definition == '')
		{
			return null;
		}
		var bitmapData:BitmapData = SkinManager.getBitmapBydefinition(definition, app);
		_widthCache = bitmapData.width;
		_heightCache = bitmapData.height;
		
		// 大小完全相等
		if (currW == _widthCache && currH == _heightCache)
		{
			return bitmapData;
		}
		switch(_type)
		{
			// 水平伸缩型
			case RetractileType.HORIZONTAL:
				if (currW != _widthCache)
				{
					bitmapData = _createRetractileBitmap(bitmapData, currW, RetractileType.HORIZONTAL);
				}
				break;
				
			// 垂直伸缩型
			case RetractileType.VERTICAL:
				if (currH != _heightCache)
				{
					bitmapData = _createRetractileBitmap(bitmapData, currH, RetractileType.VERTICAL);
				}
				break;
				
			// 完整型
			case RetractileType.WHOLE:
				if (currW != _widthCache)
				{
					bitmapData = _createRetractileBitmap(bitmapData, currW, RetractileType.HORIZONTAL);
				}
				if (currH != _heightCache)
				{
					_widthCache = bitmapData.width;
					bitmapData = _createRetractileBitmap(bitmapData, currH, RetractileType.VERTICAL);
				}
				break;
				
			default:
				break;	
		}
		return bitmapData;
	}
	
	/**
	 * 获取皮肤实例
	 * @param property		属性名称
	 **/
	public function getSkin(property:String):ISkin
	{
		
		return this[property] as ISkin;
	}

	/**
	 * 清除属性引用
	 **/
	public function clear():void
	{
		
	}
	
	
	
	
	
	
	/* ----------------------------------------------------    get / set    ----------------------------------------------------*/
	
	
	
	
	
	
	// 伸缩类型
	public function set type(value:int):void
	{
		_type = value;
	}

	
	
	
	
	
	/* ----------------------------------------------------    private    ----------------------------------------------------*/
	
	
	
	
	
	
	/**
	 * 生成伸缩位图
	 * <TODO>每次绘制四像素
	 * @param source			原始位图
	 * @param length			伸缩后总长度
	 * @param orientation		方向
	 **/
	protected function _createRetractileBitmap(source:BitmapData,length:Number,orientation:int):BitmapData
	{
		var bitmapData:BitmapData;

		// 重复绘制区域
		var drawRect:Rectangle;
		
		// 重复绘制次数
		var drawCount:int;
		
		// 伸缩区域长度
		var drawSize:Number;
		
		switch(orientation)
		{
			// 水平伸缩
			case RetractileType.HORIZONTAL:
				bitmapData = new BitmapData(length,_heightCache);
				drawRect = new Rectangle(_widthCache * 0.5 - 2, 0, 4, _heightCache);
				drawSize = length - this._leftSpace-_rightSpace;
				if (drawSize < 4)
				{
					drawSize = 4;
					length = this._leftSpace + this._rightSpace + 4;
				}
				drawCount = Math.ceil(drawSize / 4);
				for (var i:int = 0; i < drawCount; i++)
				{

					bitmapData.copyPixels(source, drawRect, new Point(_leftSpace + i * 4,0));
				}
				bitmapData.copyPixels(source, new Rectangle(0, 0, _leftSpace, _heightCache), new Point(0, 0));
				bitmapData.copyPixels(source, new Rectangle(_widthCache - _rightSpace, 0, _rightSpace, _heightCache), new Point(length - _rightSpace, 0));
				break;
				
			// 垂直伸缩
			case RetractileType.VERTICAL:
				bitmapData = new BitmapData(_widthCache, length);
				drawRect = new Rectangle(0,_heightCache * 0.5 - 2,_widthCache,4);
				drawSize = length - this._upSpace-_downSpace;
				if (drawSize < 4)
				{
					drawSize = 4;
					length = this._upSpace + this._downSpace + 4;
				}
				drawCount = Math.ceil(drawSize / 4);
				for (i = 0; i < drawCount; i++)
				{
					bitmapData.copyPixels(source, drawRect, new Point(0,_upSpace + i * 4));
				}
				bitmapData.copyPixels(source, new Rectangle(0, 0, _widthCache, _upSpace), new Point(0, 0));
				bitmapData.copyPixels(source, new Rectangle(0,_heightCache - _downSpace, _widthCache, _downSpace), new Point(0,length - _downSpace));
				break;
				
			default:
				break;
		}
		return bitmapData;
	}
	
}

}